﻿using UnityEngine;
using UnityEditor;
using System.Text;
using System.Collections.Generic;
using UnityEngine.UI;
using System.IO;

public class CheckResUsed : EditorWindow
{
    static Object obj = null;
    static List<string> resPath = new List<string>();          // 检测的资源路径
    static List<string> pList = new List<string>();              // 引用到资源的prefab路径
    static List<string> unusedList = new List<string>();    // 没被引用的资源路径

    static Dictionary<string, int> useCount = new Dictionary<string, int>();

    public Vector2 scrollPos = new Vector2(0,70);

    [MenuItem("DDZ工具/ 查找资源被引用prefab")]
    static void Init()
    {
        // Get existing open window or if none, make a new one:
        CheckResUsed window = (CheckResUsed)EditorWindow.GetWindow(typeof(CheckResUsed));
        window.Show();
    }

    void OnGUI()
    {

        obj = EditorGUILayout.ObjectField(obj, typeof(Object), true);// new Rect(3, 5, position.width - 6, 20), "File", obj,, true);

        if (obj)
        {
            string objType = obj.GetType().ToString();
            string objName = obj.name;
            string path = AssetDatabase.GetAssetPath(obj);
            //string guid = AssetDatabase.AssetPathToGUID(path);
            EditorGUILayout.LabelField(objName);

            if (GUI.Button(new Rect(3, 40, (position.width - 6)/2 -5, 20), "Check Used"))
            {
                resPath.Clear();
                pList.Clear();
                unusedList.Clear();

                CheckResUsedInPrefabs(path);
            }

            //if (GUI.Button(new Rect((position.width - 6) / 2 + 3, 40, (position.width - 6)/2 - 5, 20), "Check Prefab Use"))
            //{
            //    //resPath.Clear();
            //    //pList.Clear();
            //    //unusedList.Clear();
            //    //useCount.Clear();

            //    CheckPrefabsUseImage(path);
            //}
            EditorGUI.LabelField(new Rect(3, 60, position.width - 6, 20), "Result:", " 未被引用资源数量：" + unusedList.Count);
        }
        else
            EditorGUI.LabelField(new Rect(3, 30, position.width - 6, 20), "Missing:", "拖入文件夹或资源");

        
        if (unusedList.Count > 0)
        {

            EditorGUILayout.LabelField("");
            EditorGUILayout.LabelField("");
            scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
            //scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Width(position.width - 10), GUILayout.Height(position.height - 50));
            int count = 0;
            foreach (var unusedPath in unusedList)
            {
                Object obj = AssetDatabase.LoadAssetAtPath(unusedPath,typeof(Object));
                EditorGUILayout.ObjectField(obj, typeof(Object), true);// new Rect(3, 70 + count*25, position.width - 6, 20));
                count++;
            }
            EditorGUILayout.EndScrollView();
        }        
       
    }

    List<string> FindSpriteInPath(string path)
    {
        string[] guids = AssetDatabase.FindAssets("t:Sprite", new[] { path });
        
        Debug.Log("检查的路径下Sprite数量:" + guids.Length);
        List<string> paths = new List<string>();
        for (int i = 0; i < guids.Length; i++)
        {
            string _resPath = AssetDatabase.GUIDToAssetPath(guids[i]);
            paths.Add(_resPath);
            if (!unusedList.Contains(_resPath))
                unusedList.Add(_resPath);
        }

        return paths;
    }

    List<string> FindTextureInPath(string path)
    {
        string[] guids = AssetDatabase.FindAssets("t:Texture", new[] { path });
        Debug.Log("检查的路径下Texture数量:" + guids.Length);
        List<string> paths = new List<string>();
        for (int i = 0; i < guids.Length; i++)
        {
            string _resPath = AssetDatabase.GUIDToAssetPath(guids[i]);
            paths.Add(_resPath); 
            if (!unusedList.Contains(_resPath))
                unusedList.Add(_resPath);
        }

        return paths;
    }

    List<string> FindFontInPath(string path)
    {
        string[] guids = AssetDatabase.FindAssets("t:Font", new[] { path });
        Debug.Log("检查的路径下Font数量:" + guids.Length);
        List<string> paths = new List<string>();
        for (int i = 0; i < guids.Length; i++)
        {
            string _resPath = AssetDatabase.GUIDToAssetPath(guids[i]);
            paths.Add(_resPath);
            if (!unusedList.Contains(_resPath))
                unusedList.Add(_resPath);
        }

        return paths;
    }

    void CheckResUsedInPrefabs(string path)
    {
        Debug.Log("检查的资源路径:" + path);
       
        List<string> spritePaths = FindSpriteInPath(path);
        List<string> texturePaths = FindTextureInPath(path);
        List<string> fontPaths = FindFontInPath(path);
        
        string[] guids = AssetDatabase.FindAssets("t:Prefab", new[] { "Assets/ResourcesAB/UI" });
        Debug.Log("检查的预制文件个数:" + guids.Length);

        for (int i = 0; i < guids.Length; i++)
        {
            string filePath = AssetDatabase.GUIDToAssetPath(guids[i]);
            GameObject obj = (GameObject)AssetDatabase.LoadAssetAtPath(filePath, typeof(GameObject));

            Object _obj = new Object();
            CheckObjUsed(spritePaths, obj, _obj as Image);
            CheckObjUsed(texturePaths, obj, _obj as RawImage);
            CheckObjUsed(fontPaths, obj, _obj as Text);

            //进度条显示
            EditorUtility.DisplayCancelableProgressBar("资源检查中...", filePath, i / guids.Length * 1.0f);
        }
        EditorUtility.ClearProgressBar();

        Debug.Log(" 未被引用资源数量：" + unusedList.Count);
        if (unusedList.Count > 0)
        {
            int count = 0;
            foreach (var unusedPath in unusedList)
            {
                Debug.Log("未被引用的资源路径：" + unusedPath);

                count++;
            }
        }
    }

    int GetComInstanceID(System.Type comType, Object com)
    {
        if (comType == typeof(Image))
        {
            Image _com = com as Image;
            return _com.sprite.GetInstanceID() ;
        }
        else if (comType == typeof(RawImage))
        {
            RawImage _com = com as RawImage;
            return _com.texture.GetInstanceID();
        }
        else if (comType == typeof(Text))
        {
            Text _com = com as Text;
            return _com.font.GetInstanceID();
        }

            return 0;
    }

    // 检查预制体是否引用了资源  
    void CheckObjUsed<T>(List<string> check, GameObject obj, T comType)
    {
        string objPath = AssetDatabase.GetAssetPath(obj.GetInstanceID());
        T[] comArr = obj.transform.GetComponentsInChildren<T>(true);
        foreach (var com in comArr)
        {
            string path = AssetDatabase.GetAssetPath(GetComInstanceID(typeof(T), com as Object));
            //Debug.Log("检查的路径:" + path);
            foreach (var itemPath in check)
            {
                  
                if (path.Contains(itemPath))
                {
                    var _com = com as Component;
                    Debug.Log(itemPath + " 被引用于：" + obj.name + "  " +_com.gameObject.name);
                    //将引用过该资源的预制体路径加入列表(去重后的)
                    //if (!pList.Contains(objPath))
                    //{
                    //    pList.Add(objPath);
                    //}

                    //Debug.Log("资源被引用:" + filePath);
                    unusedList.Remove(itemPath);
                }
            }
        }
    }

    void CheckPrefabsUseImage(string path)
    {
        Debug.LogError(path);
        string[] guids = AssetDatabase.FindAssets("t:Prefab", new[] { path });
        Debug.Log("检查的预制文件个数:" + guids.Length);

        for (int i = 0; i < guids.Length; i++)
        {
            string filePath = AssetDatabase.GUIDToAssetPath(guids[i]);
            GameObject obj = (GameObject)AssetDatabase.LoadAssetAtPath(filePath, typeof(GameObject));

            Image[] imgArr = obj.transform.GetComponentsInChildren<Image>(true);
            foreach (var img in imgArr)
            {
                string _path = AssetDatabase.GetAssetPath(img.sprite.GetInstanceID());
                if (!pList.Contains(_path))
                {
                    pList.Add(_path);
                }

                if (!useCount.ContainsKey(_path))
                {
                    useCount.Add(_path, 1);
                }
                else
                {
                    useCount[_path] += 1;
                }
                    

                if (!unusedList.Contains(_path))
                {
                    unusedList.Add(_path);
                }
            }

            SpriteRenderer[] spriteRenderArr = obj.transform.GetComponentsInChildren<SpriteRenderer>(true);
            foreach (var sr in spriteRenderArr)
            {
                string _path = AssetDatabase.GetAssetPath(sr.sprite.GetInstanceID());
                if (!pList.Contains(_path))
                {
                    pList.Add(_path);
                }

                if (!unusedList.Contains(_path))
                {
                    unusedList.Add(_path);
                }

                if (!useCount.ContainsKey(_path))
                {
                    useCount.Add(_path, 1);
                }
                else
                {
                    useCount[_path] += 1;
                }
            }

            //进度条显示
            EditorUtility.DisplayCancelableProgressBar("资源检查中...", filePath, i / guids.Length * 1.0f);
        }
        EditorUtility.ClearProgressBar();

        if (pList.Count == 0)
        {
            Debug.Log("未找到引用图片");
        }
        //else
        //{
        //    foreach (var usedPath in pList)
        //    {
        //        Debug.Log("被引用于：" + usedPath);
        //    }
        //}

        Debug.Log(" 引用图片数量：" + unusedList.Count);

        if (unusedList.Count > 0)
        {
            int count = 0;
            foreach (var unusedPath in unusedList)
            {
                Debug.Log("引用图片次数："+ useCount[unusedPath] +" " + unusedPath);
                
                count++;
            }
        }
    }


    void OnInspectorUpdate()
    {
        Repaint();
    }
}